package assignment.ton.gui;
import java.awt.geom.Point2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;

import javax.swing.JPanel;
import javax.swing.border.LineBorder;

import assignment.ton.def.Action;
import assignment.ton.def.Class;
import assignment.ton.def.Util;
import assignment.ton.gui.listener.DrawPanelMouseListener;
/**
 * Class responsible for managing the classes and drawing them
 */
public class DrawPanel extends JPanel implements Printable{
	private static final long serialVersionUID = 1L;
	private MainFrame mainFrame;
	private DrawPanelMouseListener mouseListener;
	private ArrayList<Class> classList;
	public DrawPanel(MainFrame mF){
		mainFrame = mF;
		classList = new ArrayList<Class>();
		mouseListener = new DrawPanelMouseListener(mainFrame, this);
		this.setVisible(true);
		this.setPreferredSize(new Dimension(300,300));
		this.setBorder(new LineBorder(Color.black, 2));
		this.addMouseListener(mouseListener);
		this.addMouseMotionListener(mouseListener);
		this.setBackground(Util.backgroundRight());
	}
	/**
	 * Creates class frame object and passes it c
	 * @param c the class object to add
	 */
	public void addClass(Class c){
		ClassFrame classFrame = new ClassFrame(c, this, mainFrame);
		classFrame.setVisible(true);
	}
	/**
	 * @param c class to be added to the list
	 */
	public void addClassToList(Class c){
		if(findClass(c.getName())==null){
			classList.add(c);
			mainFrame.setAction(Action.NONE);
		}
	}
	/**
	 * @return the list of classes
	 */
	public ArrayList<Class> getClasses(){
		return classList;
	}
	public int getClassSize(){
		return classList.size();
	}
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		for(Class c: classList){
			c.paint(g);
		}
	}
	public void resetClassList(){
		classList = new ArrayList<Class>();
	}
	/**
	 * @param c the class to find the distance to
	 * @return the distance from the cursor to the class
	 */
	public int getDistance(Class c){
		Point2D cursorPoint, classPoint;
		cursorPoint = new Point2D.Double((double)mouseListener.getX(), (double)mouseListener.getY());
		classPoint = new Point2D.Double((double)c.getX(), (double)c.getY());
		int dist = (int)classPoint.distance(cursorPoint);
		return dist;
	}
	/**
	 * @return the closest class object to the cursor
	 */
	public Class getClosest(){
		Class returnClass = null;
		if(classList.isEmpty()) return null;
		for(Class c: classList){
			if(returnClass==null) returnClass = c;
			if(getDistance(returnClass)>getDistance(c)){
				returnClass = c;
			}
		}
		return returnClass;
	}
	/**
	 * @param n name to pass in
	 * @return class with name passed in
	 */
	public Class findClass(String n){
		Class returnClass = null;
		for(Class c: classList){
			if(c.getName().equals(n)){
				returnClass = c;
			}
		}
		return returnClass;
	}
	/**
	 * Remove class by name
	 * @param n name of class to remove
	 */
	public void removeClass(String n){
		Class c = findClass(n);
		if(c!=null){
			classList.remove(c);
		}
	}
	/**
	 * This is for getting a string array of classes
	 * @param cc the class not be included in the list
	 * @return the string array of classes
	 */
	public String[] getClassNameArray(Class cc){
		String[] data;
		int minus = 0;
		if(findClass(cc.getName())!=null){
			minus = 1;
		}
		data = new String[classList.size()-minus];
		int i = 0;
		for(Class c: classList){
			if(c!=cc){
				data[i] = c.getName();
				i++;
			}
		}
		return data;
	}
	public void printMe(){
		PrinterJob printJob = PrinterJob.getPrinterJob();
	    printJob.setPrintable(this);
	    if (printJob.printDialog())
	      try { 
	        printJob.print();
	      } catch(PrinterException pe) {
	        System.out.println("Error printing: " + pe);
	      }
	}
	@Override
	public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
		pageFormat.setOrientation(PageFormat.LANDSCAPE);
		if (pageIndex > 0) { return (NO_SUCH_PAGE); }
			Graphics2D g2d = (Graphics2D) g;
			g2d.translate(pageFormat.getImageableX(),
					pageFormat.getImageableY());
			// Turn off double buffering
			for(Class c: classList){
				c.paint(g2d);
			}
			// Turn double buffering back on
			return (PAGE_EXISTS);
		
	}

}
